package com.wy.test.protocol.cas.endpoint.ticket.generator;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Default implementation of {@link UniqueTicketIdGenerator}. Implementation
 * utilizes a DefaultLongNumericGeneraor and a DefaultRandomStringGenerator to
 * construct the ticket id.
 * <p>
 * Tickets are of the form [PREFIX]-[SEQUENCE NUMBER]-[RANDOM STRING]-[SUFFIX]
 * </p>
 */
public class DefaultUniqueTicketIdGenerator implements UniqueTicketIdGenerator {

	/**
	 * The logger instance.
	 */
	protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * The numeric generator to generate the static part of the id.
	 */
	private NumericGenerator numericGenerator;

	/**
	 * The RandomStringGenerator to generate the secure random part of the id.
	 */
	private RandomStringGenerator randomStringGenerator;

	/**
	 * Optional suffix to ensure uniqueness across JVMs by specifying unique values.
	 */
	private String suffix;

	/**
	 * Creates an instance of DefaultUniqueTicketIdGenerator with default values
	 * including a {@link DefaultLongNumericGenerator} with a starting value of 1.
	 */
	public DefaultUniqueTicketIdGenerator() {
		this(DefaultRandomStringGenerator.DEFAULT_MAX_RANDOM_LENGTH);
	}

	/**
	 * Creates an instance of DefaultUniqueTicketIdGenerator with a specified
	 * maximum length for the random portion.
	 *
	 * @param maxLength the maximum length of the random string used to generate the
	 *        id.
	 */
	public DefaultUniqueTicketIdGenerator(final int maxLength) {
		this(maxLength, null);
	}

	/**
	 * Creates an instance of DefaultUniqueTicketIdGenerator with a specified
	 * maximum length for the random portion.
	 *
	 * @param maxLength the maximum length of the random string used to generate the
	 *        id.
	 * @param suffix the value to append at the end of the unique id to ensure
	 *        uniqueness across JVMs.
	 */
	public DefaultUniqueTicketIdGenerator(final int maxLength, final String suffix) {
		setMaxLength(maxLength);
		setSuffix(suffix);
	}

	/**
	 * Creates an instance of DefaultUniqueTicketIdGenerator with a specified
	 * maximum length for the random portion.
	 *
	 * @param numericGenerator the numeric generator
	 * @param randomStringGenerator the random string generator
	 * @param suffix the value to append at the end of the unique id to ensure
	 *        uniqueness across JVMs.
	 * @since 4.1.0
	 */
	public DefaultUniqueTicketIdGenerator(final NumericGenerator numericGenerator,
			final RandomStringGenerator randomStringGenerator, final String suffix) {
		this.randomStringGenerator = randomStringGenerator;
		this.numericGenerator = numericGenerator;
		setSuffix(suffix);
	}

	@Override
	public String getNewTicketId(final String prefix) {
		final String number = this.numericGenerator.getNextNumberAsString();
		final StringBuilder buffer =
				new StringBuilder(prefix.length() + 2 + (StringUtils.isNotBlank(this.suffix) ? this.suffix.length() : 0)
						+ this.randomStringGenerator.getMaxLength() + number.length());

		buffer.append(prefix);
		buffer.append('-');
		buffer.append(number);
		buffer.append('-');
		buffer.append(this.randomStringGenerator.getNewString());

		if (this.suffix != null) {
			buffer.append(this.suffix);
		}

		return buffer.toString();
	}

	public void setSuffix(final String suffix) {
		this.suffix = StringUtils.isNoneBlank(suffix) ? '-' + suffix : null;
	}

	/**
	 * Sets max length of id generation.
	 *
	 * @param maxLength the max length
	 */
	public void setMaxLength(final int maxLength) {
		this.randomStringGenerator = new DefaultRandomStringGenerator(maxLength);
		this.numericGenerator = new DefaultLongNumericGenerator(1);
	}

}
